﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;

namespace YJKArch.AxisModule
{
	public class AixsCreator
	{
		public AixsCreator(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
		}

		public Result Create(ref string message)
		{
			Result result;
			try
			{
				Element element = this.SelectGrid();
				if (element == null)
				{
					throw new System.ArgumentNullException("not aixs");
				}
				if (element.GetType() == typeof(Grid))
				{
					bool isOffset = true;
					Grid grid =  element as Grid;
					if (grid.Curve.GetType() == typeof(Line))
					{
						isOffset = false;
					}
					AddAxisForm addAxisForm = new AddAxisForm(isOffset, this.m_Revit);
					if (addAxisForm.ShowDialog() != DialogResult.OK)
					{
						return Autodesk.Revit.UI.Result.Failed;
					}
					if (addAxisForm.IsOffset)
					{
						this.OffsetCreateAxis(grid, addAxisForm.NewName, addAxisForm.OffsetLength);
					}
					else
					{
						this.RotateCreateAxis(grid, addAxisForm.NewName, addAxisForm.RotateAngle);
					}
				}
				if (element.GetType() == typeof(MultiSegmentGrid))
				{
					AddAxisForm addAxisForm2 = new AddAxisForm(true, this.m_Revit);
					if (addAxisForm2.ShowDialog() != DialogResult.OK)
					{
						return Autodesk.Revit.UI.Result.Failed;
					}
					MultiSegmentGrid grid2 = element as MultiSegmentGrid;
					this.OffsetCreateMultiSegmentAxis(grid2, addAxisForm2.NewName, addAxisForm2.OffsetLength);
				}
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		private Element SelectGrid()
		{
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				AxisFilter axisFilter = new AxisFilter();
				Reference reference = selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, axisFilter, "选择轴线");
				Element element = this.m_Revit.Application.ActiveUIDocument.Document.GetElement(reference);
				if (element.GetType() == typeof(MultiSegmentGrid) || element.GetType() == typeof(Grid))
				{
					return element;
				}
			}
			catch (Exception)
			{
				return null;
			}
			return null;
		}

		private Result OffsetCreateMultiSegmentAxis(MultiSegmentGrid grid, string name, double offsetLength)
		{
			offsetLength = AssistFunc.mmToFeet(offsetLength);
			XYZ ptOffsetDir = this.m_Revit.Application.ActiveUIDocument.Selection.PickPoint("点选偏移方向");
			List<Curve> locationCurves = this.GetLocationCurves(grid);
			CurveLoop offsetCurveLoopWithMSGrid = this.GetOffsetCurveLoopWithMSGrid(locationCurves, offsetLength, ptOffsetDir);
			SubTransaction subTransaction = new SubTransaction(this.m_Revit.Application.ActiveUIDocument.Document);
			subTransaction.Start();
			new AxisNameManager(this.m_Revit).AddNewName(name);
			if (!MultiSegmentGrid.IsValidCurveLoop(offsetCurveLoopWithMSGrid))
			{
				throw new Exception("Create a new straight grid failed.");
			}
			ElementId typeId = grid.GetTypeId();
			SketchPlane sketchPlane = this.m_Revit.Application.ActiveUIDocument.ActiveView.SketchPlane;
			ElementId id = RevitDocumentExtension.CreateMultiSegmentGrid(this.m_Revit.Application.ActiveUIDocument.Document, typeId, offsetCurveLoopWithMSGrid, sketchPlane.Id);
			Element element = RevitVersionFuncs.GetElement(this.m_Revit.Application.ActiveUIDocument.Document, id);
			subTransaction.Commit();
			if (element == null)
			{
				throw new Exception("Create a new straight grid failed.");
			}
			MultiSegmentGrid multiSegmentGrid = element as MultiSegmentGrid;
			multiSegmentGrid.Text = name;
			foreach (ElementId id2 in multiSegmentGrid.GetGridIds())
			{
				RevitVersionFuncs.GetElement(this.m_Revit.Application.ActiveUIDocument.Document, id2).Name = name;
			}
			this.m_Revit.Application.ActiveUIDocument.Document.Regenerate();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private List<Curve> GetLocationCurves(MultiSegmentGrid grid)
		{
			List<Curve> list = new List<Curve>();
			ICollection<ElementId> gridIds = grid.GetGridIds();
			XYZ pt = null;
			for (int i = 1; i < gridIds.Count; i++)
			{
				Curve curve = (RevitVersionFuncs.GetElement(this.m_Revit.Application.ActiveUIDocument.Document, gridIds.ElementAt(i - 1)) as Grid).Curve;
				XYZ hyendPoint = curve.GetEndPoint(0);
				XYZ hyendPoint2 = curve.GetEndPoint(1);
				Curve curve2 = (RevitVersionFuncs.GetElement(this.m_Revit.Application.ActiveUIDocument.Document, gridIds.ElementAt(i)) as Grid).Curve;
				XYZ hyendPoint3 = curve2.GetEndPoint(0);
				XYZ hyendPoint4 = curve2.GetEndPoint(1);
				if (i == 1)
				{
					if (GeoUtil.IsPointEqual(hyendPoint2, hyendPoint3) || GeoUtil.IsPointEqual(hyendPoint2, hyendPoint4))
					{
						list.Add(curve);
						pt = hyendPoint2;
					}
					else
					{
						Curve item = this.CalculateReverseCurve(curve);
						list.Add(item);
						pt = hyendPoint;
					}
				}
				if (GeoUtil.IsPointEqual(pt, hyendPoint3))
				{
					list.Add(curve2);
					pt = hyendPoint4;
				}
				else if (GeoUtil.IsPointEqual(pt, hyendPoint4))
				{
					Curve item2 = this.CalculateReverseCurve(curve2);
					list.Add(item2);
					pt = hyendPoint3;
				}
			}
			return list;
		}

		private CurveLoop GetOffsetCurveLoopWithMSGrid(List<Curve> locationCurves, double offset, XYZ ptOffsetDir)
		{
			this.EstimateDirection(locationCurves, ref offset, ptOffsetDir);
			List<Curve> list = new List<Curve>();
			foreach (Curve curve in locationCurves)
			{
				if (curve.GetType() == typeof(Line))
				{
					list.Add(this.OffsetLine(curve as Line, offset));
				}
				else if (curve.GetType() == typeof(Arc))
				{
					list.Add(this.OffsetArc(this.m_Revit.Application.Application, curve as Arc, offset));
				}
			}
			for (int i = 1; i < list.Count; i++)
			{
				Curve curve2 = list[i - 1];
				Curve curve3 = list[i];
				XYZ ptNew = this.IntersectWithTwoCurves(curve2, curve3, this.m_Revit.Application.Application);
				list[i - 1] = this.ChangeEndsWithCurve(curve2, ptNew, false, this.m_Revit.Application.Application);
				list[i] = this.ChangeEndsWithCurve(curve3, ptNew, true, this.m_Revit.Application.Application);
			}
			CurveLoop curveLoop = new CurveLoop();
			foreach (Curve curve4 in list)
			{
				curveLoop.Append(curve4);
			}
			return curveLoop;
		}

		private void EstimateDirection(List<Curve> locationCurves, ref double offset, XYZ ptOffsetDir)
		{
			double num = double.MaxValue;
			int i = 0;
			int index = 0;
			while (i < locationCurves.Count)
			{
				double num2 = locationCurves[i].Distance(ptOffsetDir);
				if (num2 < num)
				{
					num = num2;
					index = i;
				}
				i++;
			}
			Curve curve = locationCurves[index];
			if (curve.GetType() == typeof(Line))
			{
				if (this.PointAtLineLeft(ptOffsetDir, curve.GetEndPoint(0), curve.GetEndPoint(1)))
				{
					offset = -offset;
					return;
				}
			}
			else if (curve.GetType() == typeof(Arc))
			{
				Arc arc = curve as Arc;
				double radius = arc.Radius;
				double num3 = arc.Center.DistanceTo(ptOffsetDir);
				if (arc.Normal.Z > 0.0)
				{
					if (num3 < radius)
					{
						offset = -offset;
						return;
					}
				}
				else if (num3 > radius)
				{
					offset = -offset;
				}
			}
		}

		private XYZ GetOffsetDirection_Line(Grid grid, XYZ ptPick)
		{
			Curve curve = grid.Curve;
			XYZ xyz = null;
			Line line = curve as Line;
			if (null != line)
			{
				xyz = this.CalculateFootPoint(line, ptPick);
			}
			XYZ xyz2 = ptPick - xyz;
			return new XYZ(xyz2.X, xyz2.Y, 0.0);
		}

		private double GetOffsetDirection_Arc(Grid grid, XYZ ptPick)
		{
			Curve curve = grid.Curve;
			XYZ xyz = null;
			Arc arc = curve as Arc;
			if (null != arc)
			{
				xyz = this.CalculateFootPoint(arc, ptPick);
			}
			double radius = arc.Radius;
			double num = arc.Center.DistanceTo(ptPick);
			double num2 = xyz.DistanceTo(ptPick);
			double result = 1.0;
			if (Math.Abs(num + num2 - radius) < 0.001)
			{
				result = 0;
			}
			return result;
		}

		public Result OffsetCreateAxis(Grid axis, string name, double offsetLength)
		{
			XYZ ptPick = null;
			try
			{
				ptPick = this.m_Revit.Application.ActiveUIDocument.Selection.PickPoint("点选偏移方向");
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			ElementId typeId = axis.GetTypeId();
			GridType type = RevitVersionFuncs.GetElement(this.m_Revit.Application.ActiveUIDocument.Document, typeId) as GridType;
			Curve curve = axis.Curve;
			Line line = curve as Line;
			if (null != line)
			{
				XYZ xyz = this.GetOffsetDirection_Line(axis, ptPick);
				if (xyz == null)
				{
					return Autodesk.Revit.UI.Result.Failed;
				}
				xyz = xyz.Normalize() * AssistFunc.mmToFeet(offsetLength);
				this.OffsetCreateLineAxis(type, line, name, xyz);
			}
			Arc arc = curve as Arc;
			if (null != arc)
			{
				double offset = this.GetOffsetDirection_Arc(axis, ptPick) * AssistFunc.mmToFeet(offsetLength);
				this.OffsetCreateArcAxis(type, arc, name, offset);
			}
			this.m_Revit.Application.ActiveUIDocument.Document.Regenerate();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private void OffsetCreateLineAxis(GridType type, Line axisLine, string name, XYZ ptDirection)
		{
			XYZ xyz = axisLine.GetEndPoint(0);
			XYZ xyz2 = axisLine.GetEndPoint(1);
			xyz += ptDirection;
			xyz2 += ptDirection;
			SubTransaction subTransaction = new SubTransaction(this.m_Revit.Application.ActiveUIDocument.Document);
			subTransaction.Start();
			try
			{
				new AxisNameManager(this.m_Revit).AddNewName(name);
				Line line = YJKLineEx.YJKGetBound(xyz, xyz2);
				Grid grid =  this.m_Revit.Application.ActiveUIDocument.Document.YjkNewGrid(line);
				grid.HyExtendToAllLevels();
				subTransaction.Commit();
				grid.Name = name;
				if (type != null)
				{
					grid.ChangeTypeId(type.Id);
				}
			}
			catch (Exception)
			{
				subTransaction.RollBack();
			}
		}

		private void OffsetCreateArcAxis(GridType type, Arc axisArc, string name, double offset)
		{
			XYZ center = axisArc.Center;
			axisArc.GetEndPoint(0);
			axisArc.GetEndPoint(1);
			double startAngle = 0.0;
			double endAngle = 0.0;
			this.GetArcAngles(axisArc, ref startAngle, ref endAngle);
			double radius = axisArc.Radius + offset;
			SubTransaction subTransaction = new SubTransaction(this.m_Revit.Application.ActiveUIDocument.Document);
			subTransaction.Start();
			new AxisNameManager(this.m_Revit).AddNewName(name);
			Arc arc = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(center, radius, startAngle, endAngle, XYZ.BasisX, XYZ.BasisY);
			Grid grid =  this.m_Revit.Application.ActiveUIDocument.Document.YjkNewGrid(arc);
			grid.HyExtendToAllLevels();
			subTransaction.Commit();
			if (grid == null)
			{
				throw new Exception("Create a new straight grid failed.");
			}
			grid.Name = name;
			if (type != null)
			{
				grid.ChangeTypeId(type.Id);
			}
		}

		private bool GetRotateDirection(Grid grid, ref bool isAnticlockwise, ref XYZ ptCenter)
		{
			Line line = grid.Curve as Line;
			if (null == line)
			{
				return false;
			}
			ptCenter = this.GetRotatePoint(line);
			if (ptCenter == null)
			{
				return false;
			}
			XYZ pt = this.m_Revit.Application.ActiveUIDocument.Selection.PickPoint("点选偏移方向");
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			XYZ ptEnd = hyendPoint + (hyendPoint2 - hyendPoint) / 2.0;
			if (this.PointAtLineLeft(pt, ptCenter, ptEnd))
			{
				isAnticlockwise = true;
			}
			else
			{
				isAnticlockwise = false;
			}
			return true;
		}

		private Result RotateCreateAxis(Grid axis, string name, double rotateAngle)
		{
			XYZ ptCenter = null;
			bool flag = true;
			if (!this.GetRotateDirection(axis, ref flag, ref ptCenter))
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			if (!flag)
			{
				rotateAngle = -rotateAngle;
			}
			ElementId typeId = axis.GetTypeId();
			GridType type = RevitVersionFuncs.GetElement(this.m_Revit.Application.ActiveUIDocument.Document, typeId) as GridType;
			Line line = axis.Curve as Line;
			if (null == line)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			this.RotateCreateLineAxis(type, line, name, ptCenter, rotateAngle);
			this.m_Revit.Application.ActiveUIDocument.Document.Regenerate();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private void RotateCreateLineAxis(GridType type, Line axisLine, string name, XYZ ptCenter, double rotateAngle)
		{
			ptCenter = new XYZ(ptCenter.X, ptCenter.Y, 0.0);
			XYZ hyendPoint = axisLine.GetEndPoint(0);
			XYZ xyz = axisLine.GetEndPoint(1);
			rotateAngle = rotateAngle / 180.0 * Math.PI;
			XYZ xyz2 = hyendPoint - ptCenter;
			xyz2 = this.RotateTo(xyz2, rotateAngle, XYZ.BasisZ);
			XYZ xyz3 = xyz - ptCenter;
			xyz3 = this.RotateTo(xyz3, rotateAngle, XYZ.BasisZ);
			XYZ startPoint = ptCenter + xyz2;
			xyz = ptCenter + xyz3;
			SubTransaction subTransaction = new SubTransaction(this.m_Revit.Application.ActiveUIDocument.Document);
			subTransaction.Start();
			Line line = YJKLineEx.YJKGetBound(startPoint, xyz);
			Grid grid =  this.m_Revit.Application.ActiveUIDocument.Document.YjkNewGrid(line);
			grid.HyExtendToAllLevels();
			subTransaction.Commit();
			if (grid == null)
			{
				throw new Exception("Create a new straight grid failed.");
			}
			new AxisNameManager(this.m_Revit).AddNewName(name);
			grid.Name = name;
			if (type != null)
			{
				grid.ChangeTypeId(type.Id);
			}
		}

		private XYZ GetRotatePoint(Line line)
		{
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			foreach (Element element in new FilteredElementCollector(this.m_Revit.Application.ActiveUIDocument.Document, this.m_Revit.Application.ActiveUIDocument.ActiveView.Id).OfClass(typeof(Grid)).ToElements())
			{
				Arc arc = (element as Grid).Curve as Arc;
				IntersectionResultArray intersectionResultArray;
				if (!(null == arc) && line.Intersect(arc, out intersectionResultArray) == SetComparisonResult.Overlap)
				{
					XYZ center = arc.Center;
					if (this.Is_Points_Collinear(hyendPoint, hyendPoint2, center))
					{
						return center;
					}
				}
			}
			return this.m_Revit.Application.ActiveUIDocument.Selection.PickPoint("点选旋转轴点");
		}

		private bool LessThan(double val1, double val2)
		{
			return val1 - val2 < -1E-09;
		}

		private bool IsEqual(double val1, double val2)
		{
			return !this.LessThan(val1, val2) && !this.LessThan(val2, val1);
		}

		private bool Is_Points_Collinear(XYZ pt1, XYZ pt2, XYZ pt3)
		{
			double num = pt2.X - pt1.X;
			double num2 = pt2.Y - pt1.Y;
			double num3 = pt2.Z - pt1.Z;
			double num4 = pt3.X - pt1.X;
			double num5 = pt3.Y - pt1.Y;
			double num6 = pt3.Z - pt1.Z;
			double num7 = num2 * num6 - num5 * num3;
			double num8 = num4 * num3 - num * num6;
			double num9 = num * num5 - num4 * num2;
			double val = num7 * num7 + num8 * num8 + num9 * num9;
			return this.IsEqual(val, 0.0);
		}

		private void GetArcAngles(Arc arc, ref double startAngle, ref double endAngle)
		{
			XYZ hyendPoint = arc.GetEndPoint(0);
			XYZ hyendPoint2 = arc.GetEndPoint(1);
			XYZ center = arc.Center;
			startAngle = XYZ.BasisX.AngleOnPlaneTo(hyendPoint - center, XYZ.BasisZ);
			endAngle = XYZ.BasisX.AngleOnPlaneTo(hyendPoint2 - center, XYZ.BasisZ);
			if (this.IsEqual(arc.Normal.Z, -1.0))
			{
				endAngle = (double)((float)XYZ.BasisX.AngleOnPlaneTo(hyendPoint - center, XYZ.BasisZ));
				startAngle = (double)((float)XYZ.BasisX.AngleOnPlaneTo(hyendPoint2 - center, XYZ.BasisZ));
			}
			if (startAngle > endAngle)
			{
				startAngle -= Math.PI*2;
			}
		}

		private XYZ TransformPoint(XYZ point, Transform transform)
		{
			double x = point.X;
			double y = point.Y;
			double z = point.Z;
			XYZ xyz = transform.get_Basis(0);
			XYZ xyz2 = transform.get_Basis(1);
			XYZ xyz3 = transform.get_Basis(2);
			XYZ origin = transform.Origin;
			double num = x * xyz.X + y * xyz2.X + z * xyz3.X + origin.X;
			double num2 = x * xyz.Y + y * xyz2.Y + z * xyz3.Y + origin.Y;
			double num3 = x * xyz.Z + y * xyz2.Z + z * xyz3.Z + origin.Z;
			return new XYZ(num, num2, num3);
		}

		private XYZ RotateTo(XYZ List, double angle, XYZ axis)
		{
			Transform transform = RevitVersionFuncs.CreateRotationAtPoint(axis, angle, new XYZ(0.0, 0.0, 0.0));
			return this.TransformPoint(List, transform);
		}

		private XYZ CalculateFootPoint(Line line, XYZ point)
		{
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			return this.CalculateFootPoint(hyendPoint, hyendPoint2, point);
		}

		private XYZ CalculateFootPoint(XYZ ptStart, XYZ ptEnd, XYZ point)
		{
			double num = Math.Sqrt((ptEnd.X - ptStart.X) * (ptEnd.X - ptStart.X) + (ptEnd.Y - ptStart.Y) * (ptEnd.Y - ptStart.Y) + (ptEnd.Z - ptStart.Z) * (ptEnd.Z - ptStart.Z));
			num = ((ptEnd.X - ptStart.X) * (point.X - ptStart.X) + (ptEnd.Y - ptStart.Y) * (point.Y - ptStart.Y) + (ptEnd.Z - ptStart.Z) * (point.Z - ptStart.Z)) / (num * num);
			double num2 = ptStart.X + (ptEnd.X - ptStart.X) * num;
			double num3 = ptStart.Y + (ptEnd.Y - ptStart.Y) * num;
			double num4 = ptStart.Z + (ptEnd.Z - ptStart.Z) * num;
			return new XYZ(num2, num3, num4);
		}

		private XYZ CalculateFootPoint(Arc arc, XYZ point)
		{
			XYZ center = arc.Center;
			XYZ hyendPoint = arc.GetEndPoint(0);
			XYZ hyendPoint2 = arc.GetEndPoint(1);
			return this.CalculateFootPoint(hyendPoint, hyendPoint2, center, point);
		}

		private XYZ CalculateFootPoint(XYZ ptStart, XYZ ptEnd, XYZ ptCenter, XYZ point)
		{
			double num = ptCenter.DistanceTo(ptStart);
			XYZ xyz = new XYZ(point.X, point.Y, ptCenter.Z) - ptCenter;
			xyz = xyz.Normalize() * num;
			return ptCenter + xyz;
		}

		private bool PointAtLineLeft(XYZ pt, XYZ ptStart, XYZ ptEnd)
		{
			double num = ptEnd.Y - ptStart.Y;
			double num2 = ptStart.X - ptEnd.X;
			double num3 = ptEnd.X * ptStart.Y - ptStart.X * ptEnd.Y;
			return num * pt.X + num2 * pt.Y + num3 < 0.0;
		}

		private Curve CalculateReverseCurve(Curve curve)
		{
			Curve result = null;
			if (curve.GetType() == typeof(Line))
			{
				Line curve2 = curve as Line;
				result = YJKLineEx.YJKGetBound(curve2.GetEndPoint(1), curve2.GetEndPoint(0));
			}
			else if (curve.GetType() == typeof(Arc))
			{
				Arc arc = curve as Arc;
				XYZ center = arc.Center;
				XYZ hyendPoint = arc.GetEndPoint(0);
				XYZ hyendPoint2 = arc.GetEndPoint(1);
				XYZ normal = arc.Normal;
				XYZ radianPnt = this.CalculatMidPoint(hyendPoint, hyendPoint2, center, normal);
				result = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(hyendPoint2, hyendPoint, radianPnt);
			}
			return result;
		}

		private Line OffsetLine(Line line, double offset)
		{
			XYZ hyendPoint = line.GetEndPoint(0);
			XYZ hyendPoint2 = line.GetEndPoint(1);
			XYZ direction = line.Direction;
			XYZ xyz = this.RotateTo(direction, -Math.PI*.5, XYZ.BasisZ) * offset;
			XYZ startPoint = hyendPoint + xyz;
			XYZ endPoint = hyendPoint2 + xyz;
			return YJKLineEx.YJKGetBound(startPoint, endPoint);
		}

		private Arc OffsetArc(Autodesk.Revit.ApplicationServices.Application app, Arc arc, double offset)
		{
			if (arc.Normal.Z < 0.0)
			{
				offset = -offset;
			}
			XYZ hyendPoint = arc.GetEndPoint(0);
			XYZ hyendPoint2 = arc.GetEndPoint(1);
			XYZ center = arc.Center;
			XYZ xyz = this.CalculatMidPoint(hyendPoint, hyendPoint2, center, arc.Normal);
			double num = arc.Radius + offset;
			XYZ xyz2 = (hyendPoint - center).Normalize() * num;
			XYZ xyz3 = (hyendPoint2 - center).Normalize() * num;
			XYZ xyz4 = (xyz - center).Normalize() * num;
			XYZ startPnt = center + xyz2;
			XYZ endPnt = center + xyz3;
			XYZ radianPnt = center + xyz4;
			return app.CreatYJKArc(startPnt, endPnt, radianPnt);
		}

		private XYZ CalculatMidPoint(XYZ ptStart, XYZ ptEnd, XYZ ptCenter, XYZ normal)
		{
			if (normal.Z < 0.0)
			{
				XYZ xyz = ptStart;
				ptStart = ptEnd;
				ptEnd = xyz;
			}
			XYZ xyz2 = ptStart - ptCenter;
			double length = xyz2.GetLength();
			xyz2 = xyz2.Normalize();
			double num = XYZ.BasisX.AngleOnPlaneTo(ptStart - ptCenter, XYZ.BasisZ);
			double num2 = XYZ.BasisX.AngleOnPlaneTo(ptEnd - ptCenter, XYZ.BasisZ);
			if (num > num2)
			{
				num -= Math.PI*2;
			}
			double angle = (num2 - num) / 2.0;
			XYZ xyz3 = this.RotateTo(xyz2, angle, XYZ.BasisZ).Normalize();
			return ptCenter + xyz3 * length;
		}

		private List<Curve> ExtendEndsWithCurve(Curve curve, Autodesk.Revit.ApplicationServices.Application revitApp)
		{
			List<Curve> list = new List<Curve>();
			if (!curve.IsBound)
			{
				list.Add(curve);
				return list;
			}
			Line line = curve as Line;
			if (null != line)
			{
				XYZ hyendPoint = line.GetEndPoint(0);
				XYZ hyendPoint2 = line.GetEndPoint(1);
				Line item = YJKLineEx.YJKGetUnBound(hyendPoint, hyendPoint2 - hyendPoint);
				list.Add(item);
				return list;
			}
			Arc arc = curve as Arc;
			if (null != arc)
			{
				XYZ center = arc.Center;
				double radius = arc.Radius;
				XYZ xyz = center + XYZ.BasisX * radius;
				XYZ radianPnt = center + XYZ.BasisY * radius;
				XYZ xyz2 = center + -XYZ.BasisX * radius;
				XYZ radianPnt2 = center + -XYZ.BasisY * radius;
				Arc item2 = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(xyz, xyz2, radianPnt);
				list.Add(item2);
				Arc item3 = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(xyz2, xyz, radianPnt2);
				list.Add(item3);
				return list;
			}
			return list;
		}

		private XYZ IntersectWithTwoCurves(Curve curve1, Curve curve2, Autodesk.Revit.ApplicationServices.Application revitApp)
		{
			List<Curve> list = this.ExtendEndsWithCurve(curve1, revitApp);
			List<Curve> list2 = this.ExtendEndsWithCurve(curve2, revitApp);
			List<XYZ> list3 = new List<XYZ>();
			foreach (Curve curve3 in list)
			{
				foreach (Curve curve4 in list2)
				{
					IntersectionResultArray intersectionResultArray;
					if (curve3.Intersect(curve4, out intersectionResultArray) == SetComparisonResult.Overlap)
					{
						foreach (object obj in intersectionResultArray)
						{
							IntersectionResult intersectionResult = (IntersectionResult)obj;
							list3.Add(intersectionResult.XYZPoint);
						}
					}
				}
			}
			XYZ hyendPoint = curve1.GetEndPoint(1);
			XYZ hyendPoint2 = curve2.GetEndPoint(0);
			XYZ xyz = hyendPoint + (hyendPoint2 - hyendPoint) / 2.0;
			double num = double.MaxValue;
			XYZ result = null;
			foreach (XYZ xyz2 in list3)
			{
				double num2 = xyz.DistanceTo(xyz2);
				if (num2 < num)
				{
					num = num2;
					result = xyz2;
				}
			}
			return result;
		}

		private Curve ChangeEndsWithCurve(Curve curve, XYZ ptNew, bool changeStartPoint, Autodesk.Revit.ApplicationServices.Application revitApp)
		{
			Curve result = null;
			Line line = curve as Line;
			if (null != line)
			{
				XYZ hyendPoint = line.GetEndPoint(0);
				XYZ hyendPoint2 = line.GetEndPoint(1);
				Line line2;
				if (changeStartPoint)
				{
					line2 = YJKLineEx.YJKGetBound(ptNew, hyendPoint2);
				}
				else
				{
					line2 = YJKLineEx.YJKGetBound(hyendPoint, ptNew);
				}
				result = line2;
			}
			Arc arc = curve as Arc;
			if (null != arc)
			{
				XYZ center = arc.Center;
				XYZ hyendPoint3 = arc.GetEndPoint(0);
				XYZ hyendPoint4 = arc.GetEndPoint(1);
				Arc arc2;
				if (changeStartPoint)
				{
					XYZ radianPnt = this.CalculatMidPoint(ptNew, hyendPoint4, center, arc.Normal);
					arc2 = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(ptNew, hyendPoint4, radianPnt);
				}
				else
				{
					XYZ radianPnt2 = this.CalculatMidPoint(hyendPoint3, ptNew, center, arc.Normal);
					arc2 = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(hyendPoint3, ptNew, radianPnt2);
				}
				result = arc2;
			}
			return result;
		}

		protected ExternalCommandData m_Revit;

		public const double _epsDouble = 1E-09;
	}
}
